tool
extends Control

class_name MyGridMapEditorMenu

onready var mnuMode: MenuButton = $HBoxContainer/mnuMode
onready var mnuModePopup: PopupMenu = ($HBoxContainer/mnuMode as MenuButton).get_popup()
onready var mnuFloor: MenuButton = $HBoxContainer/mnuFloor
onready var mnuFloorPopup: PopupMenu = ($HBoxContainer/mnuFloor as MenuButton).get_popup()
onready var txtFloor: SpinBox = $HBoxContainer/txtFloor

var current_mode: int = 0 setget set_current_mode
var current_floor: Vector3 = Vector3(0, 0, 0) setget set_current_floor

signal mode_changed(value)
signal floor_changed(value)

enum {
	MODE_NONE,
	MODE_EDIT_X_AXIS,
	MODE_EDIT_Y_AXIS,
	MODE_EDIT_Z_AXIS,
	MODE_ADD_AT_CURSOR,
	MODE_EDIT_AT_CURSOR,
	FLOOR_PREV,
	FLOOR_NEXT,
}

const MODES = [
	["None", MODE_NONE, KEY_MASK_SHIFT | KEY_Z],
	["Edit X axis", MODE_EDIT_X_AXIS, KEY_Z],
	["Edit Y axis", MODE_EDIT_Y_AXIS, KEY_X],
	["Edit Z axis", MODE_EDIT_Z_AXIS, KEY_C],
	["Add at cursor", MODE_ADD_AT_CURSOR, KEY_MASK_SHIFT | KEY_X],
	["Edit at cursor", MODE_EDIT_AT_CURSOR, KEY_MASK_SHIFT | KEY_C],
]

const FLOOR_OPS = [
	["Previous floor", FLOOR_PREV, KEY_Q],
	["Next floor", FLOOR_NEXT, KEY_E],
]

static func radio_check_item_by_id(popup: PopupMenu, begin_id: int, end_id: int, checked_id: int) -> void:
	var begin: int = 0 if begin_id < 0 else popup.get_item_index(begin_id)
	var end: int = popup.get_item_count() - 1 if end_id < 0 else popup.get_item_index(end_id)
	var checked: int = -1 if checked_id < 0 else popup.get_item_index(checked_id)
	for i in range(begin, end - begin + 1):
		if popup.is_item_checkable(i):
			popup.set_item_checked(i, i == checked)

static func radio_check_item_by_index(popup: PopupMenu, begin: int, end: int, checked: int) -> void:
	if begin < 0:
		begin = 0
	if end < 0:
		end = popup.get_item_count() - 1
	for i in range(begin, end - begin + 1):
		if popup.is_item_checkable(i):
			popup.set_item_checked(i, i == checked)

func setup():
	txtFloor.get_line_edit().connect("mouse_exited", self, "_on_txtFloor_mouse_exited")

	for o in MODES:
		mnuModePopup.add_radio_check_item(o[0], o[1], o[2])
	mnuModePopup.set_item_checked(0, true)
	mnuModePopup.connect("id_pressed", self, "_on_menu_id_pressed")

	for o in FLOOR_OPS:
		mnuFloorPopup.add_item(o[0], o[1], o[2])
	mnuFloorPopup.connect("id_pressed", self, "_on_menu_id_pressed")

	current_mode = 0
	mode_changed()

func mode_changed():
	match current_mode:
		MODE_EDIT_X_AXIS, MODE_EDIT_Y_AXIS, MODE_EDIT_Z_AXIS:
			mnuFloor.show()
			txtFloor.show()
			txtFloor.value = current_floor[current_mode - MODE_EDIT_X_AXIS]
		_:
			mnuFloor.hide()
			txtFloor.hide()

func _on_menu_id_pressed(id: int):
	match id:
		MODE_NONE, MODE_EDIT_X_AXIS, MODE_EDIT_Y_AXIS, MODE_EDIT_Z_AXIS, \
		MODE_ADD_AT_CURSOR, MODE_EDIT_AT_CURSOR:
			if current_mode != id:
				current_mode = id
				radio_check_item_by_index(mnuModePopup, -1, -1, id)
				mode_changed()
				emit_signal("mode_changed", current_mode)
		FLOOR_PREV:
			txtFloor.value -= 1
		FLOOR_NEXT:
			txtFloor.value += 1

func _on_txtFloor_value_changed(value):
	var idx: int = current_mode - MODE_EDIT_X_AXIS
	if idx >= 0 and idx < 3:
		var i: int = int(value)
		if current_floor[idx] != i:
			current_floor[idx] = i
			emit_signal("floor_changed", current_floor)

func set_current_floor(fl: Vector3):
	if current_floor != fl:
		current_floor = fl
		var idx: int = current_mode - MODE_EDIT_X_AXIS
		if idx >= 0 and idx < 3:
			txtFloor.value = fl[idx]

func set_current_mode(m: int):
	if current_mode != m:
		current_mode = m
		radio_check_item_by_index(mnuModePopup, -1, -1, m)
		mode_changed()

func _on_txtFloor_mouse_exited():
	txtFloor.get_line_edit().release_focus()
